package com.shine.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shine.context.SecurityContextHolder;
import com.shine.entity.User;
import com.shine.entity.UserRole;
import com.shine.exception.BaseException;
import com.shine.info.MenuInfo;
import com.shine.info.RoleInfo;
import com.shine.info.UserInfo;
import com.shine.mapper.MenuMapper;
import com.shine.mapper.RoleMapper;
import com.shine.mapper.UserMapper;
import com.shine.mapper.UserRoleMapper;
import com.shine.request.UserUpdateRequest;
import com.shine.security.UserPrincipal;
import com.shine.service.MenuService;
import com.shine.service.UserService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.shine.request.UserPageRequest;
import com.shine.status.ResponseStatus;
import com.shine.utils.PageUtil;
import com.shine.utils.Result;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author huihui
 * @date 2025/10/11 15:44
 * @description UserServiceImpl
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private MenuMapper menuMapper;

    @Resource
    private MenuService menuService;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Override
    public IPage<UserInfo> pageQuery(UserPageRequest request) {
        IPage<UserInfo> page = this.baseMapper.pageQuery(PageUtil.buildPage(request), request);
        if (page != null && CollectionUtils.isNotEmpty(page.getRecords())) {
            List<Long> userIdList = page.getRecords().stream().map(UserInfo::getId).toList();
            List<RoleInfo> roleInfoList = roleMapper.getByUserIdList(userIdList);
            if (CollectionUtils.isNotEmpty(roleInfoList)) {
                page.getRecords().forEach(item -> {
                    List<RoleInfo> userRoleList = roleInfoList.stream().filter(children -> children.getUserId().equals(item.getId())).toList();
                    List<Long> userRoleIdList = userRoleList.stream().map(RoleInfo::getId).toList();
                    item.setRoleList(userRoleList);
                    item.setRoleIdList(userRoleIdList);
                    // 清空密码
                    item.setPassword(null);
                });
            }
        }
        return page;
    }

    @Override
    public UserInfo getById(Long id) {
        return this.baseMapper.getById(id);
    }

    @Override
    public Boolean deleteById(Long id) {
        return this.removeById(id);
    }

    @Override
    public UserPrincipal getUser(String username) {
        if (StringUtils.isBlank(username)) {
            throw new BaseException(ResponseStatus.PARAMS_ERROR, "缺少用户名");
        }
        User user = userMapper.selectOne(
                Wrappers.<User>lambdaQuery()
                        .eq(User::getUsername, username)
        );
        if (user == null) {
            return null;
        }
        UserPrincipal userInfo = new UserPrincipal();
        BeanUtil.copyProperties(user, userInfo, true);
        List<RoleInfo> roleList = roleMapper.getByUserId(user.getId());
        userInfo.setRoleList(roleList.stream().map(RoleInfo::getCode).toList());
        List<MenuInfo> permissionList = menuService.getPermissionByUserId(user.getId());
        userInfo.setPermissionList(permissionList.stream().map(MenuInfo::getPermission).toList());
        return userInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUser(UserUpdateRequest request) {
        LambdaUpdateWrapper<User> wrapper = Wrappers.<User>lambdaUpdate()
                .eq(User::getId, request.getId())
                .set(StringUtils.isNotBlank(request.getNickName()), User::getNickName, request.getNickName())
                .set(StringUtils.isNotBlank(request.getEmail()), User::getEmail, request.getEmail())
                .set(request.getStatus() != null, User::getStatus, request.getStatus());
        int deleteCount = userRoleMapper.delete(
                Wrappers.<UserRole>lambdaQuery()
                        .eq(UserRole::getUserId, request.getId())
        );
        this.update(wrapper);
        if (CollectionUtils.isNotEmpty(request.getRoleIdList())) {
            Long userId = SecurityContextHolder.getContext().getPrincipal().getId();
            List<UserRole> saveList = request.getRoleIdList().stream().map(item -> {
                UserRole userRole = new UserRole();
                userRole.setUserId(request.getId());
                userRole.setRoleId(item);
                userRole.setCreateUser(userId);
                userRole.setUpdateUser(userId);
                userRole.setDeleted(false);
                return userRole;
            }).toList();
            userRoleMapper.saveBatch(saveList);
        }
        return true;
    }
}